#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#define ll long long
#define max(x,y) (((x)>(y))?(x):(y))
#define min(x,y) (((x)<(y))?(x):(y))

using namespace std;

struct coor
{
    int x, y;
};

struct edge
{
    int v, w;
    edge( int _v, int _w )
        :v( _v ), w( _w ) { }
};

int cas;
int n, m;
coor start, end;
map<string, int> table;
int stat_id = 0;
coor stats[ 5010 ];
vector<int> line[ 110 ];
vector<edge> adj[ 150 ];

queue<int> q;
int dist[ 110 ], inq[ 110 ];

int dist2( coor a, coor b )
{
    return ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y );
}

coor getCoor( char s[], int x,int y )
{
    coor c; c.x = x; c.y = y;
    int base = 10240;
    for ( int i = 0; i < 8; i++, base /= 2 )
    {
        if ( s[ i ] == '2' || s[ i ] == '3' ) c.x += base / 2;
        if ( s[ i ] == '1' || s[ i ] == '3' ) c.y += base / 2;
    }
    return c;
}

bool read_case( )
{
    int i, j, x, y, l;
    char str[ 10 ];
    string sstr;
    if ( !cas-- ) return false;
    scanf("%s%d%d", str, &x, &y);    
    start = getCoor( str, x, y );
    scanf("%s%d%d", str, &x, &y);
    end = getCoor( str, x, y );
    scanf("%d", &n);
    stat_id = 0;
    table.clear( );
    for ( i = 0; i < n; i++ )
    {
        scanf("%s%d%d", str, &x, &y);
        sstr = str;    
        stats[ stat_id ].x = x;
        stats[ stat_id ].y = y;    
        table[ sstr ] = stat_id++;
    }
    scanf("%d", &m);
    for ( i = 0; i < m; i++ )
    {
        line[ i ].clear( );
        scanf("%d", &l);
        for ( j = 0; j < l; j++ )
        {
            scanf("%s", str);
            sstr = str;
            line[ i ].push_back( table[ sstr ] );
        }
    }
    return true;
}

bool relax( int u, int v,int w )
{
    if ( dist[ v ] > dist[ u ] + w )
    {
        dist[ v ] = dist[ u ] + w;
        return true;
    }
    return false;
}

void solve_case( )
{
    int i, j, k, p, u, v, w;
    if ( dist2( start, end ) <= 2000 * 2000 )
    {
    printf("walk there\n");
    return ;
    }
    for ( i = 0; i < m + 2; i++ ) adj[ i ].clear( );
    for ( i = 0; i < n; i++ )
        if ( dist2( start, stats[ i ] ) <= 1000 * 1000 )
            for ( j = 0; j < m; j++ )
            {
                for ( k = 0; k < line[ j ].size( ); k++ )
                    if ( line[ j ][ k ] == i )
                        break;
                if ( k != line[ j ].size( ) )
            adj[ m ].push_back( edge( j, 0 ) );
            }
    for ( i = 0; i < n; i++ )
        if ( dist2( end, stats[ i ] ) <= 1000 * 1000 )
            for ( j = 0; j < m; j++ )
            {
                for ( k = 0; k < line[ j ].size( ); k++ )
                    if( line[ j ][ k ] == i )
                        break;
                if( k!=line[ j ].size( )){adj[ j ].push_back(edge(m + 1, 0));}
            }
    for ( i = 0; i < m; i++ )
    {
        for ( j = 0; j < m; j++ )
        {
            if ( j == i )
        continue;
            for ( k = 0; k < line[ i ].size( ); k++ )
            {
                for ( p = 0; p < line[ j ].size( ); p++ )
                    if ( line[ i ][ k ] == line[ j ][ p ] )
              break;
                if ( p != line[ j ].size( ) )
            break;
            }
            if ( k != line[ i ].size( ) )adj[ i ].push_back( edge( j, 1 ) );
        }
    }
    memset( dist, 0x3f, sizeof( dist ) );
    q.push( m );
    dist[ m ] = 0;
    while( !q.empty( ) )
    {
        u = q.front(  ); q.pop( );
        for ( i = 0; i < adj[ u ].size( ); i++ )
        {
            v = adj[ u ][ i ].v;
        w = adj[ u ][ i ].w;
            if( relax( u, v, w ) )
                q.push( v );
        }
    }
    if( dist[ m + 1 ] > 300 )
    printf("take a taxi\n");
    else
    printf("%d\n", dist[ m + 1 ] + 1);
}

int main(  )
{
    scanf("%d", &cas);
    while( read_case( ) )
        solve_case(  );
    return 0;
}
